package com.fz.us.oa.web.controller.common;

import com.fz.us.admin.base.bean.Result;
import com.fz.us.admin.base.utils.DocConverterUtil;
import com.fz.us.admin.base.utils.LogUtil;
import com.fz.us.admin.company.entity.User;
import com.fz.us.oa.core.entity.common.FileManage;
import com.fz.us.oa.core.service.common.FileManagerService;
import com.fz.us.oa.web.controller.BaseController;
import com.fz.us.oa.web.shiro.bind.annotation.CurrentUser;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfWriter;
import com.mongodb.gridfs.GridFSDBFile;
import net.sf.json.JSONObject;
import org.apache.commons.fileupload.util.Streams;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Pattern;

/**
 * 控制器 - 文件上传、读取等操作
 * ============================================================================
 * 版权所有 2016 。
 *
 * @author henryxu
 * @version 1.0 2016-12-13 。
 * ============================================================================
 */
@Controller
@RequestMapping(value = "/common/file")
public class FileController extends BaseController {

    private static final long serialVersionUID = 6492999494608560329L;

    @Autowired
    private FileManagerService fileManageService;

    //上传文件使用
    protected File filedata;
    protected String filename;
    protected String filedataFileName;
    protected String filedataContentType;
    /**
     * 上传文件
     *
     * @return
     * @throws IOException
     */
    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public Object uploadFile(HttpServletRequest request, HttpServletResponse response) throws IOException {
//        LogUtil.debug("进入/common/file/upload方法！");

        Result result = null;

        //创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());

        //判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            //转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    //取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                    if (myFileName.trim() != "") {
                        System.out.println(myFileName);

                        Map<String, Object> data = new HashMap<String, Object>();
                        FileManage fileManage = fileManageService.gridFSSave(file.getInputStream(), "APPLICATION/OCTET-STREAM", myFileName);

                        data.put("fileId", fileManage.getId());
                        data.put("state", 200);
                        data.put("name", fileManage.getName());
                        data.put("url", fileManage.getUrl());
                        data.put("msg", "上传成功");
                        result = resultService.successWithData(data);
                    }
                }
            }
        }

        if (result == null) {
            result = resultService.fail("上传文件失败");
        }

        return ajaxJson(result);
    }

    /**
     * 删除附件
     *
     * @return
     */
    @RequestMapping(value = "delete", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object delFile(@RequestParam() String keyId) {
//        LogUtil.debug("进入/common/file/delete方法！");

        FileManage fileManage = fileManageService.get(keyId);
        fileManageService.delete(fileManage);

        Result result = resultService.success("删除成功！");
        return ajaxJson(result);
    }

    /**
     * 附件列表
     *
     * @return
     */
    @RequestMapping(value = "list", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
    public Object fileList(@RequestParam(required = false) String keyId) {
//        LogUtil.debug("进入/common/file/list方法！ keyId:" + keyId);

        Map<String, Object> data = new HashMap<String, Object>();
        ArrayList<Map<String, Object>> dataRows = Lists.newArrayList();
        Map<String, Object> rMap;
        if (StringUtils.isNotEmpty(keyId)) {
            for (String fileId : StringUtils.split(keyId, ",")) {
                FileManage fileManage = fileManageService.get(fileId);
                if (fileManage == null) {
                    continue;
                }
                rMap = Maps.newHashMap();
                rMap.put("fileId", fileManage.getId());
                rMap.put("name", fileManage.getName());
                rMap.put("url", fileManage.getUrl());
                dataRows.add(JSONObject.fromObject(rMap));
            }
        }
        data.put("dataRows", dataRows);
        data.put("num", dataRows.size());
        Result result = resultService.successWithData(data);
        return ajaxJson(result);
    }

    /**
     * 附件下载
     *
     * @return
     */
    @RequestMapping(value = "download", method = RequestMethod.GET)
    public Object download(@RequestParam() String gridId, HttpServletResponse response) throws IOException {
//        LogUtil.debug("进入/common/file/download！ gridId:" + gridId);

        GridFSDBFile file = fileManageService.gridFSGet(gridId);
        if (file == null) return null;
        OutputStream out = null;
        if (file.getContentType() != null) {
            response.setContentType(file.getContentType());
        }
        String suffix = file.getFilename().substring(file.getFilename().lastIndexOf("."), file.getFilename().length());
        response.setHeader("Content-Disposition", "attachment; filename=\"" + new String(file.getFilename().getBytes() + suffix) + "\"");
        out = response.getOutputStream();
        file.writeTo(out);
        return null;
        //   return ajaxJson(resultService.success("下载成功"));
    }

    /**
     * 预览
     *
     * @return
     */
    @RequestMapping(value = "view", method = RequestMethod.GET)
    public String view(@RequestParam() String gridId, Model model, HttpServletResponse response) throws IOException {
        GridFSDBFile file = fileManageService.gridFSGet(gridId);
        InputStream in = file.getInputStream();
        String arr[] = {".ppt", ".pptx", ".doc", ".docx", ".xls", ".xlsx"};
        String suffix = file.getFilename().substring(file.getFilename().lastIndexOf("."), file.getFilename().length());
        String fileString = System.currentTimeMillis() + "";
        File dir = new File("/temp");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        File file2 = new File(dir, fileString + suffix);
        FileOutputStream out = new FileOutputStream(file2);
        Streams.copy(in, out, true);
        if (!Arrays.asList(arr).contains(suffix)) {
            response.sendRedirect("/temp/" + fileString + suffix);
            return "";
        }
        String fileName = fileString + ".swf";
        DocConverterUtil d = new DocConverterUtil("/temp/" + fileString + suffix);
        model.addAttribute("filePath", "/temp/" + fileName);
        d.conver();
        return "/com/documentView";

    }


    /**
     * 下载
     */
    @RequestMapping(value = "ueditorDownload/{id}", method = RequestMethod.GET)
    public Object download(@PathVariable String id) throws IOException {
        if (StringUtils.isNotEmpty(id)) {
            FileManage fileManage = fileManageService.get(id);
            if (fileManage != null) {
                try {
                    GridFSDBFile file = fileManageService.gridFSGet(fileManage.getGridId());
                    if (file != null) {
                        return fileDownload(file.getInputStream(), file.getFilename());
                    }
                } catch (Exception e) {
                    LogUtil.error("FileController - download: " + e.toString());
                    return ajaxJson("{\"error\": \"下载文件发生异常\"}", HttpStatus.INTERNAL_SERVER_ERROR);
                }
            }
        }
        return ajaxJson("{\"error\": \"下载失败\"}", HttpStatus.INTERNAL_SERVER_ERROR);
    }


    /**
     * 下载文件导出
     *
     * @return
     */
    @RequestMapping(value = "downloadTemplate", method = RequestMethod.GET)
    public Object downloadTemplate(@RequestParam() String filepath, String fileFullName, HttpServletResponse response) {
        try {
            if (filepath == null || filepath.indexOf("/core") == -1) {
                return null;
            }
            String fileName = URLDecoder.decode(fileFullName, "UTF-8");
            if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
            } else {
                fileName = fileFullName;
            }
            response.setContentType("text/plain;charset=UTF-8");
            response.setHeader("Pragma", "No-cache");
            response.setHeader("Cache-Control", "no-cache");
            response.setDateHeader("Expires", 0);
            response.setHeader("content-disposition", "attachment;filename=" + fileName);
            OutputStream outputStream = response.getOutputStream();
            InputStream inputStream = new FileInputStream(URLDecoder.decode(filepath, "UTF-8"));
            byte[] buffer = new byte[1024];
            int i = -1;
            while ((i = inputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, i);
            }
            outputStream.flush();
            outputStream.close();
            inputStream.close();
            outputStream = null;

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 导入对话框
     */
    @RequestMapping(value = "importDialog", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String importDialog(@CurrentUser User user, Model model, String investApprovalId) {
        model.addAttribute("investApprovalId", investApprovalId);
        return "/com/file_dialog";
    }

    /**
     * 导入excel对话框
     * @param user
     * @param model
     * @param investApprovalId
     * @return
     */
    @RequestMapping(value = "importExcelDialog", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
    public String importExcelDialog(@CurrentUser User user, Model model, String investApprovalId) {
        return "/com/excel_dialog";
    }


    /**
     * excel转化pdf并导出
     */
    @RequestMapping(value = "importExcelData", method = RequestMethod.POST)
    public Object  importExcelData(@CurrentUser User user, HttpServletRequest request, HttpServletResponse response) throws IOException, DocumentException {
        Result result = null;
        //创建一个通用的多部分解析器
        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver(request.getSession().getServletContext());
        //判断 request 是否有文件上传,即多部分请求
        if (multipartResolver.isMultipart(request)) {
            //转换成多部分request
            MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
            //取得request中的所有文件名
            Iterator<String> iter = multiRequest.getFileNames();
            while (iter.hasNext()) {
                //取得上传文件
                MultipartFile file = multiRequest.getFile(iter.next());
                if (file != null) {
                    //取得当前上传文件的文件名称
                    String myFileName = file.getOriginalFilename();
                    //如果名称不为“”,说明该文件存在，否则说明该文件不存在
                    if (myFileName.trim() != "") {
                        System.out.println(myFileName);
                        Map<String, Object> data = new HashMap<String, Object>();
                        FileManage fileManage = fileManageService.gridFSSave(file.getInputStream(), "APPLICATION/OCTET-STREAM", myFileName);
                        GridFSDBFile dbFile = fileManageService.gridFSGet(fileManage.getGridId());
                        InputStream inputStream = dbFile.getInputStream();
                        Workbook workbook = new HSSFWorkbook(inputStream);
                        workbook.setActiveSheet(0);
                        Document document = new Document();
                        BaseFont bf = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        //baseFont不支持字体样式设定.但是font字体要求操作系统支持此字体会带来移植问题.
                        Font font = new Font(bf,26);
                        font.setStyle(Font.BOLD);
                        font.getBaseFont();
                        BaseFont bf2 = BaseFont.createFont("c://windows//fonts//SIMFANG.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        Font font2 = new Font(bf2,8);
                        font2.getBaseFont();
                        Font font3 = new Font(bf2,14);
                        font3.setStyle(Font.BOLD);
                        font3.getBaseFont();
                        BaseFont bf3 = BaseFont.createFont("c://windows//fonts//simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
                        Font font4 = new Font(bf3,14);
                        font4.setStyle(Font.NORMAL);
                      /*  LogUtil.info("do");
                        LogUtil.info(getClass().getResourceAsStream("static/core"));
                        LogUtil.info(FileController.class.getClassLoader().getResource(""));
                        LogUtil.info(FileController.class.getClassLoader().getResource("/"));*/
                        File pdfFile = new File("success.pdf");
                        OutputStream outputStream = new FileOutputStream(pdfFile);
                        PdfWriter writer = PdfWriter.getInstance(document, outputStream);
                        document.open();

                        Sheet sheet = workbook.getSheetAt(0);
                        int rowNum = sheet.getLastRowNum();
                        for(int i=1; i<=rowNum; i++){
                            HSSFRow row = (HSSFRow) sheet.getRow(i);
                            String bindNo = row.getCell(0).getStringCellValue();
                            String title = row.getCell(1).getStringCellValue();
                            String no  = row.getCell(5).getStringCellValue();
                            String qi = row.getCell(6).getStringCellValue();
                            String zhong = row.getCell(7).getStringCellValue();
                            String suoqu = row.getCell(2).getStringCellValue();
                            String year = row.getCell(3).getStringCellValue();
                            String version = row.getCell(11).getStringCellValue();
                            if(i>1){
                                document.newPage();
                            }
                            PdfContentByte cb = writer.getDirectContent();
                            cb.beginText();
                            cb.setFontAndSize(bf2, 8);
                            cb.showTextAligned(PdfContentByte.ALIGN_CENTER, i+"-"+bindNo+"-中", 297, 820, 0);
                            cb.endText();
                            Paragraph t1 = new Paragraph(" ", font);
                            t1.setAlignment(1);
                            t1.setSpacingAfter(108-(title.length()-4)*13);
                            document.add(t1);
                            for(int j=0;j<title.length();j++){
                                Paragraph t2 = new Paragraph(String.valueOf(title.charAt(j)), font);
                                t2.setAlignment(1);
                                t2.setSpacingBefore(10f);
                                document.add(t2);
                            }
                            if(com.fz.us.admin.base.utils.StringUtils.isNotEmpty(version)){
                                Paragraph t9 = new Paragraph(version, font4);
                                t9.setAlignment(1);
                                t9.setSpacingBefore(10f);
                                document.add(t9);
                            }

                            Paragraph t3 = new Paragraph("卷 "+no, font3);
                            t3.setSpacingBefore(110-(title.length()-4)*13- (com.fz.us.admin.base.utils.StringUtils.isNotEmpty(version)?15:0) );
                            Paragraph t4 = new Paragraph(qi, font3);
                            Paragraph t5 = new Paragraph(year, font3);
                            Paragraph t6 = new Paragraph("总 "+zhong, font3);
                            Paragraph t7 = new Paragraph(suoqu, font3);
                            t7.setSpacingBefore(85-(title.length()-4)*10);
                            Paragraph t8 = new Paragraph("上海图书馆", font3);
                            t3.setAlignment(1);
                            t4.setAlignment(1);
                            t5.setAlignment(1);
                            t6.setAlignment(1);
                            t7.setAlignment(1);
                            t8.setAlignment(1);
                            document.add(t3);
                            document.add(t4);
                            document.add(t5);
                            document.add(t6);
                            document.add(t7);
                            document.add(t8);
                        }
                        InputStream in = new FileInputStream(pdfFile);
                        document.close();
                        writer.close();
                        outputStream.flush();
                        outputStream.close();
                        inputStream.close();
                        FileManage fileManage2 = fileManageService.gridFSSave(in, "APPLICATION/OCTET-STREAM", "success.pdf");
                      /*  String fileName = "success.pdf";
                        if (request.getHeader("User-Agent").toLowerCase().indexOf("firefox") > 0) {
                            fileName = new String(fileName.getBytes("UTF-8"), "ISO8859-1");
                        }
                        response.setContentType("text/plain;charset=UTF-8");
                        response.setHeader("Pragma", "No-cache");
                        response.setHeader("Cache-Control", "no-cache");
                        response.setDateHeader("Expires", 0);
                        response.setHeader("content-disposition", "attachment;filename=" + fileName);

                        InputStream in = null;
                        try {
                            in = new FileInputStream("/temp/"+fileName);
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                        byte[] buffer = new byte[1024];
                        int i = -1;
                        while ((i = in.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, i);
                        }*/

                        in.close();
                        data.put("fileId", fileManage2.getId());
                        data.put("state", 200);
                        data.put("name", fileManage2.getName());
                        data.put("url", fileManage2.getUrl());
                        data.put("msg", "上传成功");
                        result = resultService.successWithData(data);
                    }
                }
            }
        }

        if (result == null) {
            result = resultService.fail("上传文件失败");
        }

        return ajaxJson(result);



    }

    //检查科目编号父级是否存在
    public boolean checkSubjectNo(String subjectNo, Sheet sheet){
        boolean flag = false;
        int rowNum = sheet.getLastRowNum();
        for(int k=1; k<=rowNum; k++){
            HSSFRow row = (HSSFRow) sheet.getRow(k);
            if(row == null){
                continue;
            }
            if(StringUtils.equals(subjectNo,row.getCell(0).getStringCellValue())){
                flag = true;
                break;
            }
        }
        return flag;
    }

}
